身につけておきたいWebサイト高速化テクニック #5|リクエスト数削減テクニック01:インラインイメージ編
こんにちは、ご無沙汰しています。
Web担当の野中です。
前回、前々回と2回にわたり画像のファイルサイズを抑えるために必要な画像・画像書き出しの基礎知識について紹介してきました。
このブログに掲載している情報をさらに加筆修正したものをCodezineさまで連載しているのでぜひご覧ください。
はじめに
今回から6回にわたりリクエスト数を削減するためのテクニックを紹介していきます。
まずはじめに「インラインイメージ」について解説します。
- インラインイメージを利用する(今回)
- CSS Spriteを利用する
- SVGを埋め込む(HTML/CSS)
- Webフォントアイコンを利用する
- イメージマップを利用する
- 画像を使わずCSS3で対応する
このテクニックを使えば万事うふふ、OK〜!というわけではないのでプロジェクトの状況に合わせてテクニックを使い分けたり併用したりしましょう。
目次
- はじめに
- インラインイメージとは?
- data URI schemeとは
- Base64とは
- data URI schemeに対応しているブラウザ
- 5インラインイメージのメリット・デメリットと注意点
- インラインイメージを利用する際の判断基準と使いどころ
- 変換ツール
- 使い方
- 手間を省くには
- パフォーマンスの検証
- まとめ
画像最適化のお復習い
細かな解説に入る前に、あらためて画像最適化の全体像についてお復習いをしておきましょう。
- 画像のファイルサイズを抑える
- それぞれの画像形式について特性を知り、適切な画像形式を選択する
- ムダなメタデータの削除する
- 人の目には分からない程度に画質を調整し、ファイルサイズを抑える
- リクエスト数の削減
- インラインイメージを利用する(HTML/CSS)
- CSS Spriteを利用する
- SVGを埋め込む(HTML/CSS)
- Webフォントアイコンを利用する
- イメージマップを利用する
- 画像を使わずCSS3で対応する
- レンダリングの負荷軽減
- 実際の表示サイズと画像のサイズを合わせる
- 画像のサイズ(width,height)を指定する
1,インラインイメージとは?
インラインイメージとは、.gifや.pngなどの単体の画像ファイルではなくHTMLやCSSのソースコード内に文字列化されたデータを埋め込むテクニックのことです。
インラインイメージはURI schemeの1つ「data URI scheme」を使うことで実現できます。
URI schemeについて軽く触れておくと、みなさんがよく利用しているhttp:やhttps:、mailto:などがURI schemeと言われるものです。これらはコロン”:”の後に続くリソースの場所を示した値に対しどのような手段でアクセスするべきか示しています。
2,data URI schemeとは
URI schemeの1つであるdata URI schemeはdata:から始まります。
実際にはこのような文字列となります。サンプルコードを見てみましょう。
<img src="data:image/png:base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAACWCAIAAAC..." /> <img src="data:[MIME-type][;charset=encoding][;base64],[data]" />
2.1,data URI schemeの書式
data URI schemeの書式でどこが何を表しているのか分解してみるとこのような要素で成り立っています。
data: | image/png | ;base64 | ,iVBORw0KGgoAAAANSUhEUgAAAJYAAACWCAIAAAC... |
---|---|---|---|
URI Scheme | 形式(MIME-Type) | エンコード方式 | データ |
形式(MIME-Type)にはPNGの他にJPEGやGIF、SVGなども指定できます。
また、この他に;charset=文字コードという文字コード指定ができますが、ほとんどの場合指定しなくても問題になりません。
2.2,主な画像形式のMIME-Type
MIME-Typeなんだっけ、ということが良くあるので頻繁に利用する主な画像のMIME-Typeを紹介しておきます。
画像形式 | MIME-Type |
---|---|
PNG | image/png |
JPEG | image/jpeg |
GIF | image/gif |
SVG | image/svg+xml |
3,Base64とは
Base64とはIETFによりRFC2397で定義されている仕様で画像のバイナリデータを3バイトを6bitずつ読み込み変換テーブルで文字列に置き換えます。
文字列にすることで、HTMLに埋め込み受け取った側でデコードしバイナリデータに戻すことができます。
3.3,PNG画像をBase64エンコードしてみる
150px × 150pxのPNG画像をBase64で変換してみます。
ちなみにファイサイズは2,445バイトです。
実際に変換してみると、こんな長い文字列になります。
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
このサンプルのデータサイズは3,260バイトです。
比較すると815バイトの差があり、約37%増加したことになります。基本的にBase64エンコード後のデータは約37%増加するようです。
データサイズが大きくなるということは写真のような重たいファイルにはあまり向きません。ロゴやアイコンなどの装飾への利用に使うのが良いでしょう。
4,data URI schemeに対応しているブラウザ
対象ブラウザは最近のものであればどのブラウザも対応していますが、残念ながら古いIEには対応していません。
また、注意点としてIE8では埋め込めるサイズが32KBまでと制限されており、さらにIE8、IE9共に画像形式しか利用できません。
Chrome | Firefox | Safari | Mobile Safari (iOS6) |
Mobile Safari (iOS5) |
Mobile Safari (iOS4) |
IE10 | IE9 | IE8 | IE7 | IE6 |
---|---|---|---|---|---|---|---|---|---|---|
○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | × | × |
5,インラインイメージのメリット・デメリットと注意点
5.1,メリット
インラインイメージを使うことで画像自体のHTTPリクエストが発生しません。
例えばファイルサイズの小さな10個の画像を読み込んでいるとします。それらすべてをインラインイメージ化することで10回のHTTPリクエストを削減できます。
データサイズが37%増加するというデメリットはありますが変換前のデータが数MBでもない限りHTTPリクエストが減らせることの方が有益です。
5.2,デメリット
- IEの古いバージョンでは使えない
- Base64エンコードによりデータサイズが約37%増加する
- HTMLやCSSに直接埋め込むため画像を変える度に差し替えが必要(ツールで改善可能)
- data URI schemeで埋め込まれたデータはキャッシュされない
- 同じデータを複数箇所に表示したい場合、それぞれの場所に埋め込む必要があるためインラインイメージには向かない
5.3,注意点
- CSSの背景画像で利用する場合エンコードされた文字列には改行は含めてはいけない(Firefox5、Google Chrome17、Internet Explorer9で問題がおこるため)
- IE8ではデータサイズが32KBに制限されている
- ファイルサイズが約37%増加する
- SVGを埋め込む場合はブラウザがSVGをサポートしているかチェックが必要
6,インラインイメージを利用する際の判断基準と使いどころ
まず、前提として対象ブラウザがIE8以上であること。さらにデータ量が37%増加するので、大きなサイズの画像は利用しない方が良いでしょう。
また、CSSに埋め込むことでキャッシュを活用したり、gzip圧縮することで転送時のファイルサイズを小さくすることができます。
- ページ内で1度しか使わない画像の場合HTMLにインライン埋め込み
- 装飾としてしか意味を持たない場合はCSSのbackgroundに埋め込み
- 複数箇所で利用したい場合はCSSのbackgroundに埋め込んでクラスで指定
7,変換ツール
- duri.me
- Crystal Creation 画像ファイルのBase64エンコード
- Online sample of a base64 poperty decoding and encoding texts and files.
- Web Utils
- Data URL Maker
8,使い方
HTML,CSS共にimgタグのsrc属性やbackgroundプロパティのurl指定に埋め込むことができます。
8.1,HTMLのサンプル
<img src="data:image/png;base64,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" />
8.2,CSSのサンプル
div { background: url("data:image/png;base64,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"); }
9,手間を省くには
この記事では詳しく解説しませんが、ツールを使うことで自動化することができます。
うまく活用して開発の手間を省きましょう。画像の差し替え後も自動で変更できることが手間を省くポイントです。
9.1,HTMLの指定
- PHPやRubyでBase64 encodeする
PHPやRubyで動的にエンコードし埋め込むことで画像の差し替えにも対応できます。PHPの場合file_get_contentsとbase64_encodeを組み合わせることで実現できます。うまくキャッシュを利用できるとさらに良いでしょう。
9.2,CSSの指定
- Sass/Compassを使う
例としてSass/Compassしか上げることができませんでしたが、Sass/Compassのヘルパーを活用することで差し替えにも対応しつつ、事前にエンコードすることができます。
また、変更時に書き換えが必要なので最善ではないですがエディタでエンコードして埋め込むという方法もありますね。
たとえばSublime text 2ではEmmetパッケージを入れることでショートカットキー(Ctrl + Shift + d)一発でBase64エンコードができます。
その他に便利なツールがあればコメントで情報をいただければ追記したいと思います。
10,パフォーマンスの検証
比較の対象としてDOMContentLoaded event(DOMの構築が終わった段階で呼ばれるイベント)とLoad event(すべての読み込みが完了した段階で呼ばれるイベント)の2つが呼ばれた段階で経過している秒数をチェックします。
一般的にはDOMContentLoaded eventが速く呼ばれることが体感速度が速く感じられる指標の一つとなっています。
10.1,検証タイプ
実際にどの程度の違いになるのか、4つのタイプを比較検証したいと思います。この検証は非常に条件が限られたもので実際のWebサイトではより多くの画像が使われるため違った結果となることもあると思います。
- 一般的な埋め込み:サンプル
- 一般的な読み込み方法です。イメージタグのsrc属性を使用し画像をロード後、表示します。
- 一般的な埋め込み(CDN):サンプル
- 一般的な読み込み方法ですが高速な配信が可能なCloudFrontにある画像をロード後、表示します。
- インラインイメージ(HTML):サンプル
- HTMLでインラインイメージ使い表示します。
- インラインイメージ(CSS):サンプル
- CSSでインラインイメージを使い、CSSをHTMLに読み込んで表示します。
検証環境
検証はChromeのバージョン28を使い、シークレットウィンドウ上でDevtoolsのタイムラインを確認します。
キャッシュの影響を受けないよう無効にしています。
10.2,検証結果
タイプ | タイミング | 平均(ms) | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
HTMLへのリンクによる埋め込み | DOMContentLoaded event fired | 137.5 | 138 | 137 | 137 | 134 | 143 | 134 | 138 | 137 | 136 | 141 |
Load event fired | 407.6 | 419 | 403 | 406 | 406 | 418 | 402 | 403 | 402 | 409 | 408 | |
HTMLへのリンクによる埋め込み(CDN) | DOMContentLoaded event fired | 134.0 | 137 | 138 | 128 | 135 | 129 | 135 | 134 | 131 | 136 | 137 |
Load event fired | 190.3 | 199 | 188 | 198 | 186 | 177 | 187 | 184 | 186 | 189 | 209 | |
CSSへのリンクによる埋め込み | DOMContentLoaded event fired | 119.8 | 123 | 120 | 115 | 120 | 120 | 118 | 121 | 125 | 118 | 118 |
Load event fired | 467.3 | 481 | 463 | 445 | 466 | 470 | 462 | 471 | 489 | 468 | 458 | |
CSSへのリンクによる埋め込み(CDN) | DOMContentLoaded event fired | 123.8 | 113 | 116 | 131 | 117 | 123 | 119 | 130 | 121 | 131 | 137 |
Load event fired | 274.6 | 257 | 259 | 272 | 258 | 292 | 275 | 290 | 274 | 281 | 288 | |
インラインイメージ(HTML) | DOMContentLoaded event fired | 136.0 | 137 | 134 | 132 | 136 | 139 | 139 | 133 | 143 | 136 | 131 |
Load event fired | 138.4 | 140 | 140 | 134 | 136 | 140 | 141 | 135 | 146 | 138 | 134 | |
インラインイメージ(CSS) | DOMContentLoaded event fired | 120.1 | 125 | 134 | 135 | 135 | 135 | 136 | 129 | 135 | 138 | 134 |
Load event fired | 268.9 | 251 | 271 | 269 | 268 | 272 | 287 | 263 | 267 | 270 | 271 |
一般的な埋め込み方法の結果を見てみるとDOMContentLoaded eventに大きな違いはありません。
大きな違いはLoad eventまでの待ち時間です。これはインラインイメージの方が速い結果となりました。
詳しく見るとインラインイメージのHTMLとCSSではCSSの方が若干DOMContentLoaded eventが速いようですがCSSのHTTPリクエストが発生しているためLoad eventまでにWaitingが発生しています。ただし、一般的なWebサイトでCSSを読み込まないということはないので問題にするものではありません。
まとめ
インラインイメージではWebサイトが速く表示されたと人が感じる指標と言われているDOMContentLoaded eventに大きな影響は与えませんでした。代わりにLoad eventまでの待ち時間が短縮されるのでロゴやアイコンなどの装飾が表示されるまでの待ち時間を短縮するのに役立つことがわかりました。
IEの古いバージョンでは利用できないという制限がありますが、気にする必要のないスマートフォン向けサイトなどで積極的に利用したいテクニックですね。ちなみに、インラインイメージはCSS Spriteと併用することもできるのでアイコンなどの小さいけれど数の多い画像などをまとめてリクエスト数を削減し、画像が表示されるまでの時間を短縮することができます。
次回はCSS Spriteについて紹介します。